#ifndef _APPLICATION_H_
#define _APPLICATION_H_

#include <freertos/FreeRTOS.h>
#include <freertos/event_groups.h>
#include <freertos/task.h>
#include <string>
#include <mutex>
#include <list>
#include <web_socket.h>
#include "boards/background_task.h"
#include "boards/websocket_protocol.h"
#include "boards/button/button.h"
#include "boards/button/system_reset.h"


// 定义事件位
#define SCHEDULE_EVENT (1 << 0)
#define AUDIO_INPUT_READY_EVENT (1 << 1)
#define AUDIO_OUTPUT_READY_EVENT (1 << 2)

// 设备状态枚举
enum DeviceState {
    kDeviceStateUnknown,
    kDeviceStateStarting,
    kDeviceStateWifiConfiguring,
    kDeviceStateIdle,
    kDeviceStateConnecting,
    kDeviceStateListening,
    kDeviceStateSpeaking,
    kDeviceStateFatalError
};

class Application {
public:
    static Application& GetInstance() {
        static Application instance;
        return instance;
    }
    // 禁用通过拷贝构造函数来创建Application类对象
    Application(const Application&) = delete;
    Application& operator=(const Application&) = delete;

    // 启动初始化加载项，启动配网，启动主循环
    void Start();

    // 是否监测到语音
    bool IsVoiceDetected() const { return voice_detected_; }

    // 任务调度（扔进任务后，会在mainLoop的事件组中被调度执行）
    // 建议只执行语音交互的任务（语音底层处理建议交给后台异步调度任务执行）
    void Schedule(std::function<void()> callback);

    // set语音状态
    void SetDeviceState(DeviceState state);

    // 开始倾听(会在MainLoop中被调度执行，事件位类型：EventSchedule)
    void StartListening();
    // 停止倾听
    void StopListening();

private:
    Application(); //构造函数声明
    ~Application();//析构函数声明

    /****************以下为MainLoop中进行调度的事件组定义***********/
    // 事件组句柄
    EventGroupHandle_t event_group_;
    // 互斥锁对象（用于保证执行任务列表线程安全）
    std::mutex mutex_;
    // 任务列表（用于执行非声音事件外的其他任务，可自定义task并添加进去）
    std::list<std::function<void()>> main_tasks_;

    /*****************后台任务调度器*****************************/
    BackgroundTask* background_task_ = nullptr;

    /*****************WebSocket对象*****************************/
    WebsocketProtocol* socket_protocol_ = nullptr;


    /*****************Audio相关的状态和编码参数定义***********/
    std::chrono::steady_clock::time_point last_output_time_;
    std::list<std::vector<int16_t>> audio_decode_queue_;
    bool voice_detected_ = false;
    volatile DeviceState device_state_ = kDeviceStateUnknown;
    bool keep_listening_ = false;
    bool aborted_ = false; //是否终止

    /**********************************************************/
    // Button定义
    Button* boot_button_;
    Button* touch_button_;
    // SystemReset system_reset_;


    // 主循环（根据事件组唤醒并处理所有事件：顺序调度）
    void MainLoop();

    // 声音处理事件（录音和播放）
    void InputAudio();
    void OutputAudio();

    // ButtonIO初始化
    void InitButton();
};

#endif // _APPLICATION_H_
